package com.autumn.configurre;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

import com.autumn.runtime.cache.interceptor.MethodParamKeyGenerator;
import com.autumn.runtime.cache.interceptor.SimpleParamKeyGenerator;
import com.autumn.runtime.cache.interceptor.TargetTypeMethodParamKeyGenerator;
import com.autumn.runtime.exception.filter.AutumnExceptionFilter;
import com.autumn.runtime.exception.filter.DefaultExceptionFilterContext;
import com.autumn.runtime.exception.filter.DefaultLastExceptionFilter;
import com.autumn.runtime.exception.filter.ExceptionFilter;
import com.autumn.runtime.exception.filter.ExceptionFilterContext;
import com.autumn.runtime.exception.filter.NullPointerExceptionFilter;
import com.autumn.runtime.exception.filter.SQLExceptionFilter;
import com.autumn.runtime.exception.filter.ValidationBindExceptionFilter;

/**
 * 核芯自动配置
 * 
 * @author 杨昌国 2018-12-07 01:42:29
 */
@Configuration
public class AutumnCoreAutoConfiguration {

	/**
	 * 简单参数键生成器
	 * 
	 * @return
	 */
	@Bean(SimpleParamKeyGenerator.BEAN_NAME)
	@Primary
	@ConditionalOnMissingBean(SimpleParamKeyGenerator.class)
	public SimpleParamKeyGenerator simpleParamKeyGenerator() {
		return new SimpleParamKeyGenerator();
	}

	/**
	 * 方法与参数键生成器
	 * 
	 * @return
	 */
	@Bean(MethodParamKeyGenerator.BEAN_NAME)
	@Primary
	@ConditionalOnMissingBean(MethodParamKeyGenerator.class)
	public MethodParamKeyGenerator methodParamKeyGenerator() {
		return new MethodParamKeyGenerator();
	}

	/**
	 * 目标类型与方法与参数键生成器
	 * 
	 * @return
	 */
	@Bean(TargetTypeMethodParamKeyGenerator.BEAN_NAME)
	@Primary
	@ConditionalOnMissingBean(TargetTypeMethodParamKeyGenerator.class)
	public TargetTypeMethodParamKeyGenerator targetTypeMethodParamKeyGenerator() {
		return new TargetTypeMethodParamKeyGenerator();
	}

	/**
	 * 异常过滤上下文
	 * 
	 * @return
	 */
	@Bean
	@Primary
	@ConditionalOnMissingBean(ExceptionFilterContext.class)
	public ExceptionFilterContext exceptionFilterContext() {
		return new DefaultExceptionFilterContext();
	}

	/**
	 * 
	 * @return
	 */
	@Bean
	@ConditionalOnMissingBean(AutumnExceptionFilter.class)
	public AutumnExceptionFilter autumnExceptionFilter() {
		return new AutumnExceptionFilter();
	}

	/**
	 * 
	 * @return
	 */
	@Bean
	@ConditionalOnMissingBean(SQLExceptionFilter.class)
	public SQLExceptionFilter sqlExceptionFilter() {
		return new SQLExceptionFilter();
	}

	/**
	 * 
	 * @return
	 */
	@Bean
	@ConditionalOnMissingBean(ValidationBindExceptionFilter.class)
	public ValidationBindExceptionFilter validationBindExceptionFilter() {
		return new ValidationBindExceptionFilter();
	}

	/**
	 * 
	 * @return
	 */
	@Bean
	@ConditionalOnMissingBean(NullPointerExceptionFilter.class)
	public NullPointerExceptionFilter nullPointerExceptionFilter() {
		return new NullPointerExceptionFilter();
	}

	/**
	 * 
	 * @return
	 */
	@Bean
	@ConditionalOnMissingBean(DefaultLastExceptionFilter.class)
	public DefaultLastExceptionFilter defaultLastExceptionFilter() {
		return new DefaultLastExceptionFilter();
	}

	/**
	 * 拦截
	 * 
	 * @return
	 */
	@Bean
	public BeanPostProcessor exceptionFilterBeanPostProcessor(ExceptionFilterContext exceptionFilterContext) {
		return new BeanPostProcessor() {
			@Override
			public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
				if (bean instanceof ExceptionFilter) {
					ExceptionFilter filter = (ExceptionFilter) bean;
					exceptionFilterContext.addFilter(filter);
				}
				return bean;
			}

			@Override
			public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
				return bean;
			}
		};
	}

}
